######################################################################
# Time-stamp: <04/08/19 14:02:30 ostolop>
#
# Package: EP::Visualization::ThreewaySimilarityGraphic
#
# SVG graphic for Three-way Similarity Analysis EPC
######################################################################
package EP::Visualization::ThreewaySimilarityGraphic;

use strict;

use EP::Config;

use PDL;
use PDL::NiceSlice;
use PDL::Core;

use base qw ( EP::Visualization::Graphics );


#------------------------------------------------------
# global variables for drawing the each svg components 
#------------------------------------------------------

# margin
use constant MARGIN => 20;

# title
use constant TITLE_BAR_HEIGHT => 30;
use constant SUB_TITLE_BAR_HEIGHT => 15;
use constant TITLE_STYLE => 'font-family: sans-serif; font-size: 10pt; stroke: none; fill: blue;';

use constant GENE_BAR_HEIGHT => 15;
use constant ONE_BOX_WIDTH => 750;


# 3D Virtual Box
use constant ThreeD_VIRTUAL_BOX_WIDTH => ONE_BOX_WIDTH * 0.6;  
use constant ThreeD_VIRTUAL_BOX_HEIGHT => ONE_BOX_WIDTH * 0.4; # ThreeD_VIRTUAL_BOX_WIDTH;

use constant ThreeD_VIRTUAL_LEN_X => 60;
use constant ThreeD_VIRTUAL_LEN_Y => 60;
use constant ThreeD_VIRTUAL_LEN_Z => 60;

use constant ThreeD_VIEW_BOX_WIDTH => 100;
use constant ThreeD_VIEW_BOX_HEIGHT => 100;


# slider main
use constant SLIDER_BOX_WIDTH => ONE_BOX_WIDTH * 0.4;
use constant SLIDER_BOX_HEIGHT => ThreeD_VIRTUAL_BOX_HEIGHT; 

use constant SLIDER_IMG_BOX_WIDTH => SLIDER_BOX_WIDTH;
use constant SLIDER_IMG_BOX_HEIGHT => SLIDER_BOX_HEIGHT/6;

use constant SLIDER_TEXT_BOX_WIDTH => SLIDER_BOX_WIDTH;
use constant SLIDER_TEXT_BOX_HEIGHT => SLIDER_BOX_HEIGHT/6;

use constant ABSOLUTE_SLIDER_START_X => ThreeD_VIRTUAL_BOX_WIDTH + MARGIN + 5 + 24;
use constant ABSOLUTE_SLIDER_END_X => ABSOLUTE_SLIDER_START_X + SLIDER_BOX_WIDTH;


# 3D main
use constant ThreeD_BOX_WIDTH => ONE_BOX_WIDTH;  
use constant ThreeD_BOX_HEIGHT => ThreeD_VIRTUAL_BOX_HEIGHT;

# 3D window
use constant ThreeD_WINDOW_WIDTH => MARGIN + ThreeD_BOX_WIDTH + MARGIN;
use constant ThreeD_WINDOW_HEIGHT => TITLE_BAR_HEIGHT + ThreeD_VIRTUAL_BOX_HEIGHT + MARGIN;

# GO main
use constant MAX_GO_NO => 50;
use constant GO_ANNOTATION_HEIGHT => 15;
use constant GO_BOX_WIDTH => ONE_BOX_WIDTH;
use constant GO_BOX_HEIGHT => GENE_BAR_HEIGHT + 
                              SUB_TITLE_BAR_HEIGHT + 
                              GO_ANNOTATION_HEIGHT * MAX_GO_NO;

# GO window
use constant GO_WINDOW_WIDTH => MARGIN + GO_BOX_WIDTH + MARGIN; 
use constant GO_WINDOW_HEIGHT => TITLE_BAR_HEIGHT + GO_BOX_HEIGHT + MARGIN;



# detail - expression
use constant DETAIL_EXPRESSION_BOX_WIDTH => ONE_BOX_WIDTH;
use constant DETAIL_EXPRESSION_BOX_HEIGHT => 140;

# detail - sequence
use constant DETAIL_SEQUENCE_BOX_WIDTH => DETAIL_EXPRESSION_BOX_WIDTH;
use constant DETAIL_SEQUENCE_BOX_HEIGHT => 140;

# detail - motif
use constant DETAIL_MOTIF_BOX_WIDTH => DETAIL_EXPRESSION_BOX_WIDTH;
use constant DETAIL_MOTIF_BOX_HEIGHT => 140;

# detail - box 
use constant DETAIL_BOX_WIDTH => DETAIL_EXPRESSION_BOX_WIDTH;
use constant DETAIL_BOX_HEIGHT => GENE_BAR_HEIGHT + 
                                  SUB_TITLE_BAR_HEIGHT * 3 +
                                  DETAIL_EXPRESSION_BOX_HEIGHT + 
                                  DETAIL_SEQUENCE_BOX_HEIGHT +
                                  DETAIL_MOTIF_BOX_HEIGHT;

# detail window
use constant DETAIL_WINDOW_WIDTH => MARGIN + DETAIL_BOX_WIDTH + MARGIN; 
use constant DETAIL_WINDOW_HEIGHT =>  TITLE_BAR_HEIGHT + 
                                      DETAIL_BOX_HEIGHT +
                                      MARGIN;

# whole window
use constant TOTAL_WINDOW_WIDTH => ThreeD_WINDOW_WIDTH; # 
use constant TOTAL_WINDOW_HEIGHT => ThreeD_WINDOW_HEIGHT + 
                                    GO_WINDOW_HEIGHT +
                                    DETAIL_WINDOW_HEIGHT;  

use constant WINDOW_PRESERVE_RATIO => 'xMidYMid slice';
use constant WINDOW_STYLE => 'stroke: black; fill:white;';

# gene feature
use constant GENE_RADIUS => ( ThreeD_VIEW_BOX_WIDTH / 100 ) * 1.5;
use constant GENE_STROKE_WIDTH => ThreeD_VIEW_BOX_WIDTH / 200;
use constant GENE_STROKE => "black";
use constant GENE_COLOR => "red";
use constant GENE_STYLE => "font-family: sans-serif; font-size: 5pt; stroke: none;";


# Sub: setData
#
# PURPOSE: set the data for this module 
sub setData {
  my $self = shift;
  my %params = @_;

  die "No data supplied to ThreewaySimilarityGraphic::setData" if not defined $params{data};

  $self->{data}        = $params{data};
}

# Sub: getWidth
#
# PURPOSE:  returns the total width of the graphic, called when generating the final SVG
sub getWidth {
  return TOTAL_WINDOW_WIDTH;
}

# Sub: getHeight
#
# PURPOSE:  returns the total height of the graphic, called when generating the final SVG
sub getHeight {
  return TOTAL_WINDOW_HEIGHT;
}

# Sub: getType
#
# PURPOSE:  returns string identifying the object as a heatmap
sub getType {
  return "ThreewaySimilarity";
}

# Sub: to_svg
#
# PURPOSE:  generates the SVG for the graphic
sub to_svg {

  my $self = shift;
  my ( $svg, $height, $width, $xpos, $ypos ) = @_;

  # init the java script file
  $self->_init_script( $svg );                                                                                                               
  # draw the 3D window
  $xpos = 0;
  $ypos = 0;
  $self->_draw_3D_window( $svg, $xpos, $ypos );

  # draw the Detail window
  $xpos = 0;
  $ypos = ThreeD_WINDOW_HEIGHT;
  $self->_draw_detail_window( $svg, $xpos, $ypos );

  # draw the GO window
  $xpos = 0;
  $ypos = ThreeD_WINDOW_HEIGHT + DETAIL_WINDOW_HEIGHT;
  $self->_draw_GO_window( $svg, $xpos, $ypos );
 
  return $svg;
}

# Sub: _init_script
#
# PURPOSE:  register the script for svg file
sub _init_script {

  my $self = shift;
  my $svg = shift;
  
  # create the dynamic init script file
  my $href_filepath = "$EP::Config::h->{HTML_HREF}" . "/tmp/dynamic_ThreewaySimilarityAnalysis.js";
  my $filepath = "$EP::Config::h->{ROOT}" . "/tmp/dynamic_ThreewaySimilarityAnalysis.js";
  $self->_create_dynamic_script($filepath);

  # include the script file 
  $svg->script (  type                      => "text/javascript",
                  "a3:scriptImplementation" => "Adobe",
                  "xlink:href" => $href_filepath 
                 );
  $svg->script (  type                      => "text/javascript",
                  "a3:scriptImplementation" => "Adobe",
                  "xlink:href" => "$EP::Config::h->{HTML_HREF}" . "/static/js/ThreewaySimilarityAnalysis.js"
                 );
}

# Sub: _init_script
#
# PURPOSE:  generates the dynamic java script 
sub _create_dynamic_script {

  my $self = shift;
  my $filepath = shift;
  my $data = $self->getData();

  open FH, ">$filepath" or die "Couldn't open the file $filepath : $!";

  # generate the init function
  my $gene_no = $data->{META_valid_gene_no};
  my $input_gene = $data->{META_input_gene};

  print FH "var gGeneNo = $gene_no;\n";
  print FH "var gGOBoxY = " . SUB_TITLE_BAR_HEIGHT . ";\n";
  print FH "var gGOBoxHeight = " . GO_ANNOTATION_HEIGHT * MAX_GO_NO . ";\n";
  print FH "var gInputGene = \"" . $input_gene . "\"\n";
  print FH "var gGeneList = new Array(gGeneNo);\n\n";

  print FH "initTSA();\n\n";

  print FH "function initTSA() {\n";

  print FH "\tvar detailPicture = svgDocument.getElementById(\"detailPicture\");\n";
  print FH "\tdetailPicture.setAttribute(\"xlink:href\", \"#detail_$input_gene\");\n\n";
  print FH "\tinitGeneListener();\n}\n\n";
         

  # generate the function header
  print FH "function initGeneListener() {\n\tvar genePoint;\n\n";

  my $gene;

  my $new_gene_size = GENE_RADIUS * 2;
  my $new_gene_stroke_width = GENE_STROKE_WIDTH * 2;
  my $new_gene_stroke = "black";
  my $new_gene_color = "orange";
  my $ii=0;
  foreach $gene ( keys %$data ) {
     # check if it is the META info
     next if $gene =~ /^META/;

     # check it has the valid information
     next if $data->{$gene}->{valid} == 0;

     # register the event listener
     # this one looks doesn't work
     #print FH "\tvar motifImg = svgDocument.getElementById( \"img_motif_" , $gene, "\" );\n";
     #print FH "\tmotifImg.addEventListener( \"mousedown\", clickmotif, false );\n\n";

     # register the event listener
     print FH "\tgenePoint = svgDocument.getElementById( \"" , $gene, "\" );\n";
     print FH "\tgenePoint.addEventListener( \"mousedown\", eventmouse, false );\n\n";

     # store the gene name and it's x,y,z values
     print FH "\tgGeneList[$ii] = new Object();\n";
     print FH "\tgGeneList[$ii][\"name\"] = \"$gene\";\n";
     print FH "\tgGeneList[$ii][\"x\"] = " . $data->{$gene}->{expression} * 100 . " ;\n";
     print FH "\tgGeneList[$ii][\"y\"] = " . $data->{$gene}->{sequence} * 100 . " ;\n";
     print FH "\tgGeneList[$ii][\"z\"] = " . $data->{$gene}->{motif} * 100 . " ;\n";

     $ii++;
 
  }
  print FH "}\n\n";


  # this one looks doesn't work
  #print FH "function clickmotif(evt)\n{\n";
  #print FH "\tvar urlName = evt.target.getAttribute(\"urlname\");\n\n";
  #print FH "\twindow.open(\"urlName\", \"motifwindow\", \"width=400, height=300, location=no, menubar=no, status=no, toolbar=yes, scrollbars=yes, resizable=yes\");\n\n";
  #print FH "}\n\n";

  print FH "function eventmouse(evt)\n{\n";
  print FH "\tvar detailPicture = svgDocument.getElementById(\"detailPicture\");\n";
  print FH "\tvar newGeneName = evt.target.id;\n\n";

  print FH "\t// restore original points\n";
  print FH "\tvar xGeneName = detailPicture.getAttribute(\"xlink:href\")\n";
  print FH "\txGeneName = xGeneName.substr(8, xGeneName.length);\n";
  print FH "\tif(xGeneName != \"None\") {\n";
  print FH "\t   var xGenePoint = svgDocument.getElementById(xGeneName);\n";
  print FH "\t   var xGenePointR = xGenePoint.getAttribute(\"r\");\n";
  print FH "\t   xGenePoint.setAttribute(\"r\", \"" . GENE_RADIUS . "\");\n";
  print FH "\t   xGenePoint.setAttribute(\"stroke\", \"" . GENE_STROKE . "\");\n";
  print FH "\t   xGenePoint.setAttribute(\"stroke-width\", \"" . GENE_STROKE_WIDTH . "\");\n";
  # print FH "\t   xGenePoint.setAttribute(\"fill\", \"" . GENE_COLOR . "\");\n";


  print FH "\t   var xGeneNameText = svgDocument.getElementById(\"text\" + xGeneName);\n";
  print FH "\t   xGeneNameText.getFirstChild().setNodeValue(\"\");\n";
  print FH "\t   if(xGeneName == newGeneName && xGenePointR == " . $new_gene_size . ") return; \n";
  print FH "\t}\n\n";
                                                                                
  print FH "\t// set new detailed information\n";
  print FH "\tdetailPicture.setAttribute(\"xlink:href\", \"#detail_\" + newGeneName);\n";
                                                                                
  print FH "\t// set new points larger\n";
  print FH "\tevt.target.setAttribute(\"r\", \"$new_gene_size\");\n";
  print FH "\tevt.target.setAttribute(\"stroke-width\", \"$new_gene_stroke_width\");\n";
  print FH "\tevt.target.setAttribute(\"stroke\", \"$new_gene_stroke\");\n";
  print FH "\tevt.target.setAttribute(\"fill\", \"$new_gene_color\");\n\n";
                                                                                
  print FH "\t// set the name of new point larger\n";
  print FH "\tvar GeneNameText = svgDocument.getElementById(\"text\" + newGeneName);\n";
  print FH "\tGeneNameText.setAttribute(\"style\", \"" . GENE_STYLE . "\");\n";
  print FH "\tGeneNameText.getFirstChild().setNodeValue(newGeneName);\n";
  print FH "}\n\n";
 
  close FH;
}


# Sub: _draw_3D_window
#
# PURPOSE:  draw 3D window which contains '3D virtual box' and 'slider box' 
sub _draw_3D_window {
  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;

  # make the window svg
  my $g = $svg->group( id => '3D window group',
                       transform => "translate($xpos,$ypos)" );

  my $window = $g->tag( 'svg', 
	standalone => "no",
	id => '3D_window',
	x => 0,
	y => 0,
	width => ThreeD_WINDOW_WIDTH,
	height => ThreeD_WINDOW_HEIGHT,
	viewBox => '0 0 ' . ThreeD_WINDOW_WIDTH . ' ' . ThreeD_WINDOW_HEIGHT,
        preserveaspectRatio => WINDOW_PRESERVE_RATIO ); 
 

  # draw the window outline
  $window->rectangle( id=>'3D window outline',
		      x => 0,
                      y => 0,
                      width => ThreeD_WINDOW_WIDTH,
                      height => ThreeD_WINDOW_HEIGHT - MARGIN/2,
                      style => WINDOW_STYLE );

  # draw the title bar
  $window->text( id => '3D window title',
                 x => MARGIN,
                 y => TITLE_BAR_HEIGHT * 2/3,
                 style => TITLE_STYLE,
           )->cdata('Relationship based on (EXPRESSION, SEQUENCE, MOTIF)');


  # draw the 3D coordiante main svg
  $xpos = MARGIN;
  $ypos = TITLE_BAR_HEIGHT;
  $self->_draw_3D_coordiante_main( $window, $xpos, $ypos );

  # draw the slider main svg
  $xpos = MARGIN + ThreeD_VIRTUAL_BOX_WIDTH; # MARGIN;
  $ypos = TITLE_BAR_HEIGHT; #TITLE_BAR_HEIGHT + ThreeD_BOX_HEIGHT + MARGIN/2;
  $self->_draw_slider_main( $window, $xpos, $ypos );

}

# Sub: _draw_3D_coordiante_main 
#
# PURPOSE:  draw '3D virtual box' and 'genes'  
sub _draw_3D_coordiante_main {
  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;

  # create the new svg for the parent svg
  my $g = $svg->group( id => '3D coordinate main',
                       transform => "translate($xpos,$ypos)" );

  my $window = $g->tag( 'svg',
	standalone => "no",
	id => '3D_coordiante_main',
	x => 0,
	y => 0,
	width => ThreeD_VIRTUAL_BOX_WIDTH,
	height => ThreeD_VIRTUAL_BOX_HEIGHT,
	viewBox => '0 0 ' . ThreeD_VIEW_BOX_WIDTH . ' ' . ThreeD_VIEW_BOX_HEIGHT,
        preserveaspectRatio => WINDOW_PRESERVE_RATIO ); 

  # draw the lines for 3D coordinate
  my $coordinate_points = $self->_init_3D_coordinate();
  $self->_draw_3D_coordinate( $window, $coordinate_points );

  # draw the 2D gene points
  $self->_draw_genes( $window, $coordinate_points );
}

# Sub: _init_3D_coordinate 
#
# PURPOSE:  initialize the 3D coordinates for drawing the virtual box 
sub _init_3D_coordinate {
  
  my $self = shift;
  my $point;

  $point->{p0}->{x} = 0;
  $point->{p0}->{y} = ThreeD_VIRTUAL_LEN_Z;

  $point->{p1}->{x} = ThreeD_VIRTUAL_LEN_X;
  $point->{p1}->{y} = ThreeD_VIRTUAL_LEN_Z;

  $point->{p2}->{x} = ThreeD_VIEW_BOX_WIDTH - ThreeD_VIRTUAL_LEN_X;
  $point->{p2}->{y} = ThreeD_VIEW_BOX_HEIGHT;

  $point->{p3}->{x} = ThreeD_VIEW_BOX_WIDTH;
  $point->{p3}->{y} = ThreeD_VIEW_BOX_HEIGHT;

  $point->{p4}->{x} = 0;
  $point->{p4}->{y} = 0; 

  $point->{p5}->{x} = ThreeD_VIRTUAL_LEN_Z;
  $point->{p5}->{y} = 0; 

  $point->{p6}->{x} = ThreeD_VIEW_BOX_WIDTH - ThreeD_VIRTUAL_LEN_X;
  $point->{p6}->{y} = ThreeD_VIEW_BOX_HEIGHT - ThreeD_VIRTUAL_LEN_Z;

  $point->{p7}->{x} = ThreeD_VIEW_BOX_WIDTH;
  $point->{p7}->{y} = ThreeD_VIEW_BOX_HEIGHT - ThreeD_VIRTUAL_LEN_Z;

  return $point;
}


# Sub: _draw_3D_coordinate 
#
# PURPOSE:  draw 3D coordinate virtual box  
sub _draw_3D_coordinate {

  my $self = shift;
  my $svg = shift;
  my $coordinate_point = shift;
  
  # line styles
  my $line_style = 'stroke-width: 0.5; stroke: black; fill:black;';
  my $dot_line_style = 'stroke-dasharray: 1 1; stroke-width: 0.5; stroke: black; fill:black;';


  # draw the line between the coordinate_point (second arg) and the coordiante_point (third arg)
  $self->_draw_line( $svg, $coordinate_point, 6, 7, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 2, 6, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 2, 3, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 3, 7, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 4, 6, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 5, 7, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 0, 2, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 4, 5, $line_style );
  $self->_draw_line( $svg, $coordinate_point, 0, 4, $line_style );

  $self->_draw_line( $svg, $coordinate_point, 0, 1, $dot_line_style );
  $self->_draw_line( $svg, $coordinate_point, 1, 3, $dot_line_style );
  $self->_draw_line( $svg, $coordinate_point, 1, 5, $dot_line_style );

  # draw the line arrow cap
  my $arrow = 2;
  $svg->line( x1 => $coordinate_point->{p1}->{x},
              y1 => $coordinate_point->{p1}->{y},
              x2 => $coordinate_point->{p1}->{x} - $arrow,
              y2 => $coordinate_point->{p1}->{y} - $arrow,
              style => $line_style );
  $svg->line( x1 => $coordinate_point->{p1}->{x},
              y1 => $coordinate_point->{p1}->{y},
              x2 => $coordinate_point->{p1}->{x} - $arrow,
              y2 => $coordinate_point->{p1}->{y} + $arrow,
              style => $line_style );

  $svg->line( x1 => $coordinate_point->{p4}->{x},
              y1 => $coordinate_point->{p4}->{y} + 0.5 * $arrow,
              x2 => $coordinate_point->{p4}->{x} - $arrow,
              y2 => $coordinate_point->{p4}->{y} + $arrow,
              style => $line_style );
  $svg->line( x1 => $coordinate_point->{p4}->{x},
              y1 => $coordinate_point->{p4}->{y} + 0.5 * $arrow,
              x2 => $coordinate_point->{p4}->{x} + $arrow,
              y2 => $coordinate_point->{p4}->{y} + $arrow,
              style => $line_style );

  $svg->line( x1 => $coordinate_point->{p2}->{x} - 0.5 * $arrow,
              y1 => $coordinate_point->{p2}->{y} - 0.5 * $arrow,
              x2 => $coordinate_point->{p2}->{x} - 0.5 * $arrow,
              y2 => $coordinate_point->{p2}->{y} - 1.5 * $arrow,
              style => $line_style );
  $svg->line( x1 => $coordinate_point->{p2}->{x} - 0.5 * $arrow,
              y1 => $coordinate_point->{p2}->{y} - 0.5 * $arrow,
              x2 => $coordinate_point->{p2}->{x} - 1.5 * $arrow,
              y2 => $coordinate_point->{p2}->{y} - 0.5 * $arrow,
              style => $line_style );

  # mark the (0,0) point and (100,100) point
  $svg->circle( cx => $coordinate_point->{p0}->{x},
                cy => $coordinate_point->{p0}->{y},
                r => 0.7,
                style => "fill: black" );

  my $text_style = "font-family: sans-serif; font-size: 3pt; stroke: none;"; 
  my $input_gene = $self->getData()->{META_input_gene};
  $svg->text(   x => $coordinate_point->{p0}->{x} - 3*$arrow,
                y => $coordinate_point->{p0}->{y} - $arrow,
                style => $text_style )->cdata('(0,0)');

  $svg->text(   x => $coordinate_point->{p7}->{x} - 3*$arrow,
                y => $coordinate_point->{p7}->{y} - $arrow,
                style => $text_style )->cdata('(100,100)');

  $svg->text(   x => $coordinate_point->{p7}->{x} - 3*$arrow,
                y => $coordinate_point->{p7}->{y} - 3*$arrow,
                style => $text_style . " fill: blue;" )->cdata("$input_gene");

  # mark the data name 
  $svg->text(   x => $coordinate_point->{p0}->{x} + 10*$arrow,
                y => $coordinate_point->{p0}->{y} - $arrow,
                style => "$text_style fill: blue;" )->cdata('expression');

  $svg->text(   x => $coordinate_point->{p0}->{x} + 7*$arrow,
                y => $coordinate_point->{p0}->{y} + 10*$arrow,
                style => "$text_style fill: blue;" )->cdata('sequence');

  $svg->text(   x => $coordinate_point->{p0}->{x} - 3*$arrow,
                y => $coordinate_point->{p0}->{y} - 15*$arrow,
                style => "$text_style fill: blue;" )->cdata('motif');

}

# Sub: _draw_genes 
#
# PURPOSE:  draw genes inside the 3D virtual box 
sub _draw_genes {

  my $self = shift;
  my $svg = shift;
  my $coordinate_point = shift;

  my $data = $self->getData();
  my $R = 1;


  my $gene;
  foreach $gene ( keys %$data ) {
     # check if it is the META info
     next if $gene =~ /^META/;

     # check it has the valid information
     next if $data->{$gene}->{valid} == 0;

     # similarity has the range from 0 to 1    
     my $x = $data->{$gene}->{expression} * 100;
     my $y = $data->{$gene}->{sequence} * 100;
     my $z = $data->{$gene}->{motif} * 100;

     # compute the 2D coordinate
     my $adjusted3DX = ThreeD_VIRTUAL_LEN_X * ($x/100);
     my $adjusted3DY = ( ThreeD_VIEW_BOX_HEIGHT - ThreeD_VIRTUAL_LEN_Z ) * ($y/100);
     my $adjusted3DZ = ThreeD_VIRTUAL_LEN_Z * ($z/100);

     my $tmpY = $coordinate_point->{p1}->{y} + $adjusted3DY;
     my $tmpX1 = $coordinate_point->{p0}->{x} + $adjusted3DX;
     my $tmpY1 = $coordinate_point->{p0}->{y};
     my $tmpX2 = $coordinate_point->{p2}->{x} + $adjusted3DX;
     my $tmpY2 = $coordinate_point->{p2}->{y}; 

     my $X = ( ($tmpX2-$tmpX1)/($tmpY2-$tmpY1) ) * ( $tmpY - $tmpY2 ) + $tmpX2;
     my $Y = $tmpY - $adjusted3DZ;

     # draw the gene
     $svg->circle( id => $gene,
                   cx => $X,
                   cy => $Y,
                   x => $x,
                   y => $y,
                   z => $z,
                   r => GENE_RADIUS,
                   stroke => GENE_STROKE,
                   'stroke-width' => GENE_STROKE_WIDTH,
                   fill => GENE_COLOR );

     # draw the title of the gene
     $svg->text( id => "text$gene",
                 transform => "translate(-10, -3)",
                 x => $X,
                 y => $Y,
                 style => GENE_STYLE )->cdata( " " ); 
  }
}

# Sub: _draw_line 
#
# PURPOSE: draw line between the coordinate points 
sub _draw_line {
  my $self = shift;
  my $svg = shift;
  my $coordinate_point = shift; 
  my $p1 = shift;
  my $p2 = shift;
  my $style = shift;

  $p1 = "p" . $p1;
  $p2 = "p" . $p2;
  $svg->line( id => $p1 . $p2 ,
              x1 => $coordinate_point->{$p1}->{x},
              y1 => $coordinate_point->{$p1}->{y},
              x2 => $coordinate_point->{$p2}->{x},
              y2 => $coordinate_point->{$p2}->{y},
              style => $style  
  );
}


# Sub: _draw_slider_main 
#
# PURPOSE: draw the 'sliders' and 'slider texts' 
sub _draw_slider_main {

  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;

  # create the new svg for the parent svg
  my $g = $svg->group( id => 'slider main',
                       transform => "translate($xpos,$ypos)" );

  # create the new svg for the parent svg
  my $window = $g->tag( 'svg', 
	standalone => "no",
	id => 'slider_main',
	x => 0,
	y => 0,
	width => SLIDER_BOX_WIDTH,
	height => SLIDER_BOX_HEIGHT,
	viewBox => '0 0 ' . SLIDER_BOX_WIDTH . ' ' . SLIDER_BOX_HEIGHT,
        preserveaspectRatio => WINDOW_PRESERVE_RATIO ); 


  # draw the rectangle for event handling
  $window->rectangle( x => 0,
                      y => 0,
	              width => SLIDER_BOX_WIDTH,
	              height => SLIDER_BOX_HEIGHT,
                      onmouseup => "endDrag()",
                      "pointer-events" => "visible",
                      style => "fill: none;" );


  # draw the sliders
  $xpos = 0;

  $ypos = 0;
  $self->_draw_slider_text( $window, $xpos, $ypos, "X", "EXPRESSION" ); 

  $ypos += SLIDER_TEXT_BOX_HEIGHT;
  $self->_draw_slider( $window, $xpos, $ypos, "X" ); 

  $ypos += SLIDER_IMG_BOX_HEIGHT;
  $self->_draw_slider_text( $window, $xpos, $ypos, "Y", "SEQUENCE" ); 

  $ypos += SLIDER_TEXT_BOX_HEIGHT;
  $self->_draw_slider( $window, $xpos, $ypos, "Y" ); 

  $ypos += SLIDER_IMG_BOX_HEIGHT;
  $self->_draw_slider_text( $window, $xpos, $ypos, "Z", "MOTIF" ); 

  $ypos += SLIDER_TEXT_BOX_HEIGHT;
  $self->_draw_slider( $window, $xpos, $ypos, "Z" ); 
}

# Sub: _draw_slider 
#
# PURPOSE: draw the slider 
sub _draw_slider {

  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;
  my $title = shift; 

  my $startX = $xpos + ABSOLUTE_SLIDER_START_X;  
  my $endX = $xpos + ABSOLUTE_SLIDER_END_X; 

  my $group = $svg->group( id => "slider$title",
                           transform => "translate($xpos,$ypos)",
                           onmousedown => "moveSlider(evt, \"$title\", $startX, $endX)" );

  $group->rectangle( x => 0,
                     y => 0,
                     width => SLIDER_IMG_BOX_WIDTH,
                     height => 20,  # should be SLIDER_IMG_BOX_HEIGHT ?
                     style => "fill: #c0c0c0" );

  $group->line( x1 => 5,
                y1 => 6,
                x2 => SLIDER_IMG_BOX_WIDTH-5,
                y2 => 6,
                style => "stroke: black; stroke-width:2;" );

  $group->line( x1 => 5,
                y1 => 8,
                x2 => SLIDER_IMG_BOX_WIDTH-5,
                y2 => 8,
                style => "stroke: white; stroke-width:2;" );

  # generate the path
  my $path_d = "";
  for(my $i=5; $i<SLIDER_IMG_BOX_WIDTH; $i += 20) {
	$path_d = $path_d . "M$i,16, $i, 20 ";
  }
  $group->path( d => $path_d,
                style => "stroke: black; fill:none;" );

  # generate the slider thumb 1
  $self->_draw_slider_thumb( $group, 0, 0, 0, $title, "thumb1" );
  $self->_draw_slider_thumb( $group, SLIDER_IMG_BOX_WIDTH-10, 0, 100, $title, "thumb2" );
}


# Sub: _draw_slider_text 
#
# PURPOSE:  draw the slider explanation text 
sub _draw_slider_text {

  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;
  my $title = shift; 
  my $text = shift;

  my $text_style = "font-family: sans-serif; stroke: none; fill: blue;";

  $svg->text( transform => "translate($xpos,$ypos)",
              x => 0,
              y => SLIDER_TEXT_BOX_HEIGHT * 1/2 )->cdata("$text");
              
  $svg->text( transform => "translate($xpos,$ypos)",
              id => "sliderText$title" . "_thumb1",
              x => 0, 
              y => SLIDER_TEXT_BOX_HEIGHT * 3/4,
              style => $text_style ) -> cdata('0 %'); 

  $svg->text( transform => "translate($xpos,$ypos)",
              x => SLIDER_TEXT_BOX_WIDTH*0.45,
              y => SLIDER_TEXT_BOX_HEIGHT * 3/4 )->cdata("to");

  $svg->text( transform => "translate($xpos,$ypos)",
              id => "sliderText$title" . "_thumb2",
              x => SLIDER_TEXT_BOX_WIDTH*0.6, 
              y => SLIDER_TEXT_BOX_HEIGHT * 3/4,
              style => $text_style ) -> cdata('100 %'); 

}

# Sub: _draw_slider_thumb
#
# PURPOSE: draw the slider thumb 
sub _draw_slider_thumb {

  my $self = shift;
  my $parent = shift;
  my $xpos = shift;
  my $ypos = shift;
  my $real_loc = shift;
  my $title = shift; 
  my $sub_title = shift;

  my $startX = ABSOLUTE_SLIDER_START_X;  
  my $endX = ABSOLUTE_SLIDER_END_X; 

  my $group = $parent->group( id => "slider$title" . "_" . "$sub_title",
                  onmousedown => "startDrag(\'$title" . "_". "$sub_title\')",
                  onmouseup => "endDrag(\'$title" . "_". "$sub_title\')",
#                  onmousemove => "doDrag(evt, \'$title" . "_". "$sub_title\', $startX, $endX )",
                  transform => "translate($xpos,$ypos)",
                  realLoc => $real_loc );

  $group->path( d => "M1,2 1,12 5,15 9,12 9,2 Z",
                style => "stroke: none; fill: #c0c0a0;" );
  
  $group->path( d => "M9,1 1,1 1,11",
                style => "stroke: white; fill: none;" );
        
  $group->path( d => "M5,16 10,12 10,2",
                style => "stroke: black; fill: none;" );

}

# Sub: _draw_GO_window 
#
# PURPOSE:  draw GO window 
sub _draw_GO_window {

  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;

  # to make transform to work, we should define the group 
  # then we can put anywhere this GO window using transform
  my $g = $svg->group( id => 'GO group',
                       transform => "translate($xpos,$ypos)" );

  my $window = $g->tag( 'svg',
             id => "GO window",
             x => 0, 
             y => 0, 
             width => GO_WINDOW_WIDTH,
             height => GO_WINDOW_HEIGHT,
             viewBox => "0 0 " . GO_WINDOW_WIDTH . " " . GO_WINDOW_HEIGHT,
             preserveaspectRatio => "xMidYMid slice" );

  # draw the rectangle
  $window->rectangle( id=>'GO window outline',
		      x => 0,
                      y => 0,
                      width => GO_WINDOW_WIDTH,
                      height => GO_WINDOW_HEIGHT - MARGIN/2,
                      style => WINDOW_STYLE );

  # draw the title bar
  $window->text( id => 'GO window title',
                 x => MARGIN,
                 y => TITLE_BAR_HEIGHT * 2/3,
                 style => TITLE_STYLE )->cdata('Selected Gene Summary');

  # draw the GO main
  $xpos = MARGIN;
  $ypos = TITLE_BAR_HEIGHT;
  $self->_draw_GO_main($window, $xpos, $ypos);                  

}

# Sub: _draw_GO_main 
#
# PURPOSE:  draw GO main  
sub _draw_GO_main {

  my $self = shift;
  my $window = shift;
  my $xpos = shift;
  my $ypos = shift;

  my $data = $self->getData();

  my $g = $window->group( id => 'GO main group',
                          transform => "translate($xpos,$ypos)" );

  # create the new svg for the parent svg
  my $main = $g->tag( 'svg', 
	standalone => "no",
	id => 'GO main',
	x => 0,
	y => 0,
	width => GO_BOX_WIDTH,
	height => GO_BOX_HEIGHT,
	viewBox => '0 0 ' . GO_BOX_WIDTH . ' ' . GO_BOX_HEIGHT,
        preserveaspectRatio => WINDOW_PRESERVE_RATIO ); 
  
  # get the summary info from the data
  my $input_gene = $data->{META_input_gene};
  chomp($input_gene);
  chomp($input_gene);

  my $gene_no = $data->{META_valid_gene_no};

  # draw the summary part
  my $text_style = "font-family: sans-serif; font-size: 9pt; stroke: none;"; 
  $main->text( x => 0,  
               y => SUB_TITLE_BAR_HEIGHT * 0.5, 
               style => "$text_style fill: black;" )
             ->cdata( "Total Gene" ) ;

  $main->text( id => "summaryText", 
               x => 70, 
               y => SUB_TITLE_BAR_HEIGHT * 0.5, 
               style => "$text_style fill: blue;" )
              ->cdata( $gene_no );

  $main->text( x => 100, 
               y => SUB_TITLE_BAR_HEIGHT * 0.5, 
               style => "$text_style fill: black;" )
              ->cdata( "selected" );


  # draw the annotation part
  my $gene;
  my $Y=0;

  $Y = $self->_draw_GO_line( $main, $data, $input_gene, $Y, 1 );

  foreach $gene ( keys %$data ) {
     # stop if the annotation number exceeds the max no
     last if $Y>=MAX_GO_NO ;

     # check if it is the META info
     next if $gene =~ /^META/;

     # check it has the valid information
     next if $data->{$gene}->{valid} == 0;

     # if input gene comes, ignore it
     next if $gene eq $input_gene;

     $Y = $self->_draw_GO_line( $main, $data, $gene, $Y, 0 );
  }
}


# Sub: _draw_GO_line 
#
# PURPOSE:  draw GO term for one gene 
sub _draw_GO_line {

  my $self = shift;
  my $window = shift;
  my $data = shift;
  my $gene = shift; 
  my $Y = shift;
  my $is_input_gene = shift; 

  my $text_style = "font-family: sans-serif; font-size: 9pt; stroke: none;"; 
  my $gene_name_length = 65;
  my $GO_term_length = (GO_BOX_WIDTH - $gene_name_length)/2; 

  my $index_Y = $Y;
  if($is_input_gene) {
     $Y =  SUB_TITLE_BAR_HEIGHT + $Y;   
  }
  else {
     $Y =  SUB_TITLE_BAR_HEIGHT + $Y * GO_ANNOTATION_HEIGHT;   
  }

  # determine the number of GO terms
  my $tmp_go_p = $data->{$gene}->{go_P};
  my $tmp_go_f = $data->{$gene}->{go_F};
  my @array_go_p = keys %$tmp_go_p;
  my @array_go_f = keys %$tmp_go_f;
  my $size_go_p = 0 + @array_go_p;
  my $size_go_f = 0 + @array_go_f;
  my $size;
  if( $size_go_p >= $size_go_f ) {
      $size = $size_go_p;
  }
  else {
      $size = $size_go_f;
  }

  # generate the svg
  my $main = $window->svg( id => "GO_line_$gene", 
                           x => 0,
                           y => $Y,
                           width => GO_BOX_WIDTH,
                           height => GO_ANNOTATION_HEIGHT * $size ); 

  my $i=0;
  while($size>0) {
     # stop if the annotation number exceeds the max no
     last if $index_Y>=MAX_GO_NO ;

     # draw the annotation for input gene
     # emphasize the input gene
     if( $is_input_gene ) {
         $main->rectangle( x => 0,
                    y => $i * GO_ANNOTATION_HEIGHT + 2, # GENE_BAR_HEIGHT # + SUB_TITLE_BAR_HEIGHT, 
                    width => GO_BOX_WIDTH,
                    height => GO_ANNOTATION_HEIGHT, 
                    style => "fill :#FFE4E1" );
     }

     # draw the GO Process
     $main->text( id => "GO_process_id_$i" . "_$gene",
                  x => $gene_name_length, 
                  y => ($i + 1) * GO_ANNOTATION_HEIGHT * 0.8, # GENE_BAR_HEIGHT  + SUB_TITLE_BAR_HEIGHT + 
                  style => "$text_style fill: blue;" )->cdata( "$data->{$gene}->{go_P}->{$array_go_p[$i]}" );

     # draw the GO Function
     $main->text( id => "GO_function_id_$i" . "_$gene",
                  x => $gene_name_length + $GO_term_length, 
                  y => ($i + 1) * GO_ANNOTATION_HEIGHT * 0.8, # GENE_BAR_HEIGHT + SUB_TITLE_BAR_HEIGHT + 
                  style => "$text_style fill: blue;" )->cdata( "$data->{$gene}->{go_F}->{$array_go_f[$i]}" );

     # draw the GO Component 
     #$main->text( id => "GO_component_$gene",
     #             geneName => "",
     #             x => $gene_name_length + $GO_term_length * 2, 
     #             y => GENE_BAR_HEIGHT + SUB_TITLE_BAR_HEIGHT + $index * GO_ANNOTATION_HEIGHT, 
     #             style => "$text_style fill: blue;" )->cdata( "COMPONENT $input_gene" );

     $size--;
     $index_Y++;
     $i++;
  }

  # draw the gene name
  $main->text( id => "GO$gene",
                  x => 0, 
                  y => GO_ANNOTATION_HEIGHT * 0.8, 
                  style => "$text_style fill: blue;" )->cdata( "$gene" );

  return $index_Y;
}


# Sub: _draw_detail_window 
#
# PURPOSE: draw the detail window 
sub _draw_detail_window {

  my $self = shift;
  my $svg = shift;
  my $xpos = shift;
  my $ypos = shift;

  # to make transform to work, we should define the group 
  # then we can put anywhere this window using transform
  my $g = $svg->group( id => 'detail window group',
                       transform => "translate($xpos,$ypos)" );

  my $window = $g->tag( 'svg',
             id => "detail window",
             x => 0, 
             y => 0, 
             width => DETAIL_WINDOW_WIDTH, 
             height => DETAIL_WINDOW_HEIGHT, 
             viewBox => "0 0 " . DETAIL_WINDOW_WIDTH . " " . DETAIL_WINDOW_HEIGHT,
             preserveaspectRatio => "xMidYMid slice", 
             'xml:space' => 'preserve' );         

  # draw the rectangle
  $window->rectangle( id=>'detail window outline',
		      x => 0,
                      y => 0,
                      width => DETAIL_WINDOW_WIDTH,
                      height => DETAIL_WINDOW_HEIGHT - MARGIN/2,
                      style => WINDOW_STYLE );
                                                                                             
  # draw the title bar
  $window->text( id => 'detail window title',
                 x => MARGIN,
                 y => TITLE_BAR_HEIGHT * 2/3,
                 style => TITLE_STYLE )->cdata( "Detailed Gene Relationship" );

  # draw the detail main
  $xpos = MARGIN;
  $ypos = TITLE_BAR_HEIGHT;
  $self->_draw_detail_main( $window, $xpos, $ypos );

}


# Sub: _draw_detail_main 
#
# PURPOSE: draw the detail main 
sub _draw_detail_main {

  my $self = shift;
  my $window = shift;
  my $xpos = shift;
  my $ypos = shift;

  my $data = $self->getData();

  # to make transform to work, we should define the group 
  # then we can put anywhere this window using transform
  my $g = $window->group( id => 'detail main group',
                          transform => "translate($xpos,$ypos)" );

  my $main = $g->tag( 'svg',
             id => "detail main",
             x => 0, 
             y => 0,
             width => DETAIL_BOX_WIDTH,
             height => DETAIL_BOX_HEIGHT,
             viewBox => "0 0 " . DETAIL_BOX_WIDTH . " " .DETAIL_BOX_HEIGHT, 
             preserveaspectRatio => "xMidYMid slice" );

  my $defs = $main->tag( 'defs' );

  # draw the detail for no selection yet
  my $input_gene = $data->{META_input_gene};
  $self->_draw_detail( $defs, $input_gene, "None" ); 

  # generate the detail for all genes
  my $gene;
  foreach $gene ( keys %$data ) {
     # check if it is the META info
     next if $gene =~ /^META/;

     # check it has the valid information
     next if $data->{$gene}->{valid} == 0;

     $self->_draw_detail( $defs, $input_gene, $gene ); 
  }

  # generate the use for dynamically changing pictures
  $main->tag( 'use',
                id => "detailPicture",
                'xlink:href' => "#detail_None",
                x => 0,
                y => 0 );
}

# Sub: _draw_detail_sub_title 
#
# PURPOSE: draw the sub title for each detail window ( 'expression', 'motif', 'sequence' ) 
sub _draw_detail_sub_title {

  my $self = shift;
  my $parent = shift;
  my $input_gene = shift;
  my $gene = shift;

  my $text_style = "font-family: sans-serif; font-size: 9pt; fill: blue;"; 

  my $sub_g = $parent->group( id => "detail_sub_title_$gene" ); #style => 

  # emphasize the input gene
  $sub_g->rectangle( x => 0,
                      y => 0, # 2, # + SUB_TITLE_BAR_HEIGHT, 
                      width => DETAIL_BOX_WIDTH,
                      height => SUB_TITLE_BAR_HEIGHT, 
                      style => "fill :#FFE4E1" );

  $sub_g->text( x => 0,
	    y => GENE_BAR_HEIGHT * 0.7,
            style => "$text_style" )
            ->cdata("Input Gene : $input_gene");

  $sub_g->text( x => DETAIL_BOX_WIDTH / 2,
	    y => GENE_BAR_HEIGHT * 0.7,
            style => "$text_style" )
            ->cdata("Selected Gene : $gene");


}

# Sub: _draw_detail 
#
# PURPOSE:  draw the detail svgs for 3 data types  
sub _draw_detail {

  my $self = shift;
  my $parent = shift;
  my $input_gene = shift;
  my $gene = shift;

  my $data = $self->getData();

  my $window = $parent->group( id => "detail_$gene" );

  $self->_draw_detail_sub_title( $window, $input_gene, $gene );
  
  return if( $gene eq "None" );

  my $xpos = 0;
  my $ypos = GENE_BAR_HEIGHT ;
  $self->_draw_sub_detail( $window,
                           "expression", 
                           "Expression Pattern ( X : samples  Y : expression )", 
                           DETAIL_EXPRESSION_BOX_WIDTH, DETAIL_EXPRESSION_BOX_HEIGHT,
                           $gene, $xpos, $ypos);

  $xpos = 0;
  $ypos += DETAIL_EXPRESSION_BOX_HEIGHT + SUB_TITLE_BAR_HEIGHT;
  $self->_draw_sub_detail( $window, 
                           "sequence",
                           "Sequence Alignment", 
                           DETAIL_SEQUENCE_BOX_WIDTH, DETAIL_SEQUENCE_BOX_HEIGHT,
                           $gene, $xpos, $ypos);

  $xpos = 0;
  $ypos += DETAIL_SEQUENCE_BOX_HEIGHT + SUB_TITLE_BAR_HEIGHT;
  $self->_draw_sub_detail( $window, 
                           "motif",
                           "Motif Matching", 
                           DETAIL_MOTIF_BOX_WIDTH, DETAIL_MOTIF_BOX_HEIGHT,
                           $gene, $xpos, $ypos);
}

# Sub: _draw_sub_detail 
#
# PURPOSE:  draw the each detail svg  
sub _draw_sub_detail {

  my $self = shift;
  my $window = shift;
  my $id = shift;
  my $title = shift;
  my $width = shift;
  my $height = shift;
  my $gene = shift;
  my $xpos = shift;
  my $ypos = shift;

  my $sub_title_style = "font-family: sans-serif; font-size: 9pt; stroke: none; fill: black;";
  my $text_style = "font-family: sans-serif; font-size: 8pt; stroke: none; fill: blue;";

  my $group = $window->group( id => "sub_detail_$id" . "_$gene",
                              transform => "translate($xpos, $ypos)" );

  $group->text( x => 0,
                y => SUB_TITLE_BAR_HEIGHT * 0.8,
                style => $sub_title_style )
               ->cdata("$title"); 

  # draw the svg dynamically 
  my $data = $self->getData();
  my $input_gene = $data->{META_input_gene};

  $ypos += SUB_TITLE_BAR_HEIGHT;
  my $img_group = $window->group( id => "sub_detail_img_$id" . "_$gene",
                                  transform => "translate($xpos, $ypos)" );
  if ($id eq "expression") {
     $self->_create_expression_svg($img_group, $data, $input_gene, $gene, $text_style);
  }
  elsif ($id eq "sequence") {
     $self->_create_sequence_svg($img_group, $data, $input_gene, $gene, $text_style);
  }
  elsif($id eq "motif") {
     $self->_create_motif_svg($img_group, $data, $input_gene, $gene, $text_style);
  }

  $group->rectangle( x => 0, 
                     y => SUB_TITLE_BAR_HEIGHT, 
                     width => $width,
                     height => $height,
                     style => "stroke: black; fill: none;" ); 

}

# Sub: _create_expression_svg 
#
# PURPOSE: create the expression svg file for one input gene and a pair gene 
sub _create_expression_svg {
  my $self = shift;
  my $g = shift;
  my $data = shift;
  my $input_gene = shift;
  my $gene = shift;
  my $text_style = shift;

  my $gene_exp_id = $data->{$gene}->{exp_id};
  my $input_gene_exp_id = $data->{$input_gene}->{exp_id};
  my $exp_dataset = $data->{META_exp_dataset};   # PDL 

  my $exp_data = $exp_dataset(:, pdl[$input_gene_exp_id, $gene_exp_id] ); 

  my $width = DETAIL_EXPRESSION_BOX_WIDTH - 5;
  my $height = DETAIL_EXPRESSION_BOX_HEIGHT - SUB_TITLE_BAR_HEIGHT; 
  my $style;

  # generated image doesn't seem to have given height and width  
  my $lineplot= new EP::Visualization::LineGraphic ( 
                    data => $exp_data,
                    plot_height => $height,
                    cell_width => $width );

  my $svg = $g->tag( 'svg',
                      width => $width,
                      height => $height,
                      x => 0,    # to make the digits to be shown
                      y => 0,
                      standalone => "no" );

  my $svg_content = $lineplot->to_svg( $svg, $height, $width, 0, 0 );
}


# Sub: _create_sequence_svg 
#
# PURPOSE: create the sequence svg file for one input gene and a pair gene 
sub _create_sequence_svg {

  my $self = shift;
  my $g = shift;
  my $data = shift;
  my $input_gene = shift;
  my $gene = shift;
  my $text_style = shift;

  # compute the image of height
  my $img_height = ( DETAIL_MOTIF_BOX_HEIGHT - GENE_BAR_HEIGHT ) / 2;


  # draw the input gene title
  $g->text( x => 0,
            y => GENE_BAR_HEIGHT / 2,
            style => $text_style
           )->cdata("$input_gene , $gene");

  # draw the image
  $g->image( x => 0,
             y => GENE_BAR_HEIGHT,
             width => DETAIL_SEQUENCE_BOX_WIDTH,
             height => DETAIL_SEQUENCE_BOX_HEIGHT - GENE_BAR_HEIGHT,
             'xlink:href' => "$EP::Config::h->{TSA_DATA_URL}" . "/align/$input_gene/$gene.aln.svg" ); 

}


# Sub: _create_motif_svg 
#
# PURPOSE: create the movif svg file for one input gene and a pair gene 
sub _create_motif_svg {

  my $self = shift;
  my $g = shift;
  my $data = shift;
  my $input_gene = shift;
  my $gene = shift;
  my $text_style = shift;

  # compute the image of height
  my $img_height = ( DETAIL_MOTIF_BOX_HEIGHT - GENE_BAR_HEIGHT ) / 2;


  # draw the input gene title with anchor, but it doesn't work now
  #my $protein_name = $data->{$input_gene}->{motif_protein}; 
  #my $url = "http://www.ebi.ac.uk/interpro/ISpy?ac=" . $protein_name . "&mode=single";
  #$g->anchor( 'xlink:href' => $url, 'target'=>"new_window" );

  $g->text( x => 0,
            y => GENE_BAR_HEIGHT / 2,
            style => $text_style )->cdata("$input_gene");


  # draw the input gene with anchor, but it doesn't work now
  # $g->anchor( 'xlink:href' => $url, 'target' => "new_window" ); 
  $g->image( id => "img_motif_$gene" . "_$input_gene",
             x => 50,
             y => GENE_BAR_HEIGHT,
             width => 100 * $data->{$input_gene}->{motif_no}, 
             height => 30, 
             'xlink:href' => $data->{$input_gene}->{motif_url}); 

            # try to make this img clickable, tried this one.
            # but still doesn't work
            # onmousedown => "window.open(\"$url\", \"motifwindow\", \"width=400, height=300, location=no, menubar=no, status=no, toolbar=yes, scrollbars=yes, resizable=yes\");",


  # draw the pair gene title
  $g->text( x => 0,
            y => GENE_BAR_HEIGHT + $img_height,
            style => $text_style )->cdata("$gene");


  # change the color when only one motif is shown for both genes
  my $motif_url = $data->{$gene}->{motif_url};
  if( $data->{$input_gene}->{motif_no} == 1 &&  $data->{$gene}->{motif_no} == 1 &&
      $input_gene ne $gene ) { 
      # replace the color
      $motif_url = substr( $motif_url, 0, length($motif_url)-1 ) . "1";
  }      

  # draw the image
  $g->image( id => "img_motif_$gene",
             x => 50,
             y => GENE_BAR_HEIGHT * 2 + $img_height,
             width => 100 * $data->{$gene}->{motif_no}, 
             height => 30, #$img_height,
             'xlink:href' => $motif_url);

}


# Sub: _dump
# 
# PURPOSE: debugging purpose 
sub _dump {

  my $debug_file = shift;
  my $data = shift;
  my $title = shift;

  use Data::Dumper;

  my $dumper = Data::Dumper->new( [$data], [$title] );
  my $dump_list = join "..../n" , $dumper->Dump; 

  open FH, ">$debug_file";
  print FH $dump_list;
  close FH; 

}

sub htbr_buttons {
  return { id     => 'btn_export',
	   icon   => "$EP::Config::h->{HTML_HREF}/static/images/gui_icons/save.png",
	   tip    => 'Blah blah...',
	   action => "alert('btn_export pressed')" };
}
 
1;
